package com.qianda.qdminiapp.security;

import com.qianda.qdminiapp.common.util.JsonUtils;
import com.qianda.qdminiapp.controller.Result;
import com.qianda.qdminiapp.common.exception.ExceptionCode;
import com.qianda.qdminiapp.common.exception.SimpleException;
import com.qianda.qdminiapp.common.exception.SystemException;
import org.apache.commons.lang3.StringUtils;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authentication.event.InteractiveAuthenticationSuccessEvent;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;

/**
 * @ClassName LoginFilter
 * @Author cw
 * @Date 2019/07/01
 **/
public class LoginFilter extends AbstractAuthenticationProcessingFilter {

    private static Logger LOGGER = LoggerFactory.getLogger(LoginFilter.class);

    private static final String REQUEST_PATH = "/login";
    private static final String REQUEST_METHOD = "POST";

    private  TokenManager tokenManager;

    /**
     * 创建登录过滤器
     *
     * @param authManager  认证管理器
     * @param tokenManager 令牌管理器
     */
    public LoginFilter(AuthenticationManager authManager, TokenManager tokenManager) {
        super(new AntPathRequestMatcher(REQUEST_PATH, REQUEST_METHOD));
        if (authManager == null) {
            throw new IllegalArgumentException("AuthenticationManager is required");
        }
        if (tokenManager == null) {
            throw new IllegalArgumentException("TokenManager is required");
        }
        setAuthenticationManager(authManager);
        this.tokenManager = tokenManager;
    }

    public LoginFilter(AuthenticationManager authManager) {
        super(new AntPathRequestMatcher(REQUEST_PATH, REQUEST_METHOD));
        setAuthenticationManager(authManager);
    }

    @Override
    public Authentication attemptAuthentication(
            HttpServletRequest req,
            HttpServletResponse resp) throws AuthenticationException {

        if (shouldIntercept(req)) {
        }



        String username = req.getParameter("code");
        String password = req.getParameter("password");

        if(StringUtils.isBlank(username)){
            throw new SystemException();
        }

        username = username.trim();

        UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
        authRequest.setDetails(authenticationDetailsSource.buildDetails(req));

        return getAuthenticationManager().authenticate(authRequest);
    }

    @Override
    protected void successfulAuthentication(
            HttpServletRequest req,
            HttpServletResponse resp,
            FilterChain chain,
            Authentication authResult) throws IOException, ServletException {

        if (logger.isDebugEnabled()) {
            logger.debug("Authentication success."
                    + " Updating SecurityContextHolder to contain: " + authResult);
        }

        SecurityContextHolder.getContext().setAuthentication(authResult);

        if (eventPublisher != null) {
            eventPublisher.publishEvent(new InteractiveAuthenticationSuccessEvent(authResult, getClass()));
        }

        // User userDetails = (User) authResult.getPrincipal();

        // 生成令牌放到响应头
        Token token = tokenManager.createToken(authResult);
        System.out.println(token.getId());
        resp.addHeader(AuthenticationFilter.TOKEN_HEADER, token.getId());

        resp.setCharacterEncoding("utf-8");
        resp.setContentType("application/json");

        SecurityUser user = (SecurityUser) authResult.getPrincipal();
        Map<String, Object> forRender = new HashMap<>(2);
        forRender.put("id", user.getId());
        forRender.put("username", user.getUsername());
        forRender.put("token",token.getId());
        forRender.put("qqb",user.getQqb());
        System.out.println("登录成功,Token: "+token.getId());
        LOGGER.info("登录成功,token:"+token.getId());
        // 身份认证成功返回用户详情数据给客户端
        resp.getWriter().write(JsonUtils.toJson(Result.success(forRender)));

    }

    @Override
    protected void unsuccessfulAuthentication(
            HttpServletRequest req,
            HttpServletResponse resp,
            AuthenticationException failed) throws IOException, ServletException {

        if (logger.isDebugEnabled()) {
            logger.debug("Authentication request failed: " + failed.toString(), failed);
        }
        throw new SimpleException(ExceptionCode.EX_HTTP_ACCESS_DENIED);

        // 身份认证失败的情况
    /*if (failed instanceof DisabledException) {
      resp.setCharacterEncoding("utf-8");
      resp.setContentType("application/json");
      PrintWriter pw = resp.getWriter();
      pw.write(JsonUtils.toJson(Result.failure(90009, "用户账户被禁用")));
    } else {*/
        //throw new AuthenticateFailedException(failed.getMessage());
        // }
    }


    /**
     * 返回是否拦截请求
     *
     * @param req 当前的请求
     * @return 是否拦截请求
     */
    private boolean shouldIntercept(HttpServletRequest req) {
        return false;
    }

}
